#ifndef MQCONNECTIONPOOL_H
#define MQCONNECTIONPOOL_H

#include <QObject>
#include <QMutex>
#include <QWaitCondition>
#include <QTimer>
#include <QDateTime>
#include <QQueue>
#include <QLoggingCategory>
#include <memory>
#include <amqp.h>
#include "mqconfigmanager.h"

Q_DECLARE_LOGGING_CATEGORY(connectionpool)

/**
 * @brief 连接信息结构体
 */
struct MQConnectionInfo {
    std::unique_ptr<amqp_connection_state_t_, void(*)(amqp_connection_state_t_*)> connection;
    bool inUse;                    ///< 是否正在使用
    QDateTime lastUsed;            ///< 最后使用时间
    QDateTime createdTime;         ///< 创建时间
    int errorCount;                ///< 错误计数
    bool isValid;                  ///< 连接是否有效
    
    /**
     * @brief 构造函数
     */
    MQConnectionInfo() 
        : connection(nullptr, [](amqp_connection_state_t_* conn) {
            // 空的删除器，避免自动析构时的重复释放
        })
        , inUse(false)
        , errorCount(0)
        , isValid(false) {}
        
    /**
     * @brief 安全释放连接
     */
    void safeReleaseConnection() {
        if (connection && connection.get() && isValid) {
            amqp_connection_state_t_* conn = connection.get();
            if (conn) {
                try {
                    amqp_connection_close(conn, AMQP_REPLY_SUCCESS);
                    amqp_destroy_connection(conn);
                } catch (...) {
                    // 忽略关闭过程中的异常
                }
            }
            connection.reset();
            isValid = false;
        }
    }
    
    /**
     * @brief 设置连接
     */
    void setConnection(amqp_connection_state_t_* conn) {
        connection.reset(conn);
        isValid = (conn != nullptr);
    }
};

/**
 * @brief MQ连接池类
 * 负责管理RabbitMQ连接的创建、分配、回收
 * 遵循单一职责原则，专注于连接池管理
 */
class MQConnectionPool : public QObject
{
    Q_OBJECT
    
public:
    /**
     * @brief 构造函数
     * @param config 连接配置
     * @param poolSize 连接池大小
     * @param parent 父对象
     */
    explicit MQConnectionPool(const MQConnectionConfig& config, int poolSize, QObject* parent = nullptr);
    
    /**
     * @brief 析构函数
     */
    ~MQConnectionPool();
    
    /**
     * @brief 初始化连接池
     * @param config 连接配置
     * @return 是否初始化成功
     */
    bool initialize(const MQConnectionConfig& config);
    
    /**
     * @brief 获取连接
     * @param timeoutMs 超时时间（毫秒），-1表示无限等待
     * @return 连接状态指针，nullptr表示获取失败
     */
    amqp_connection_state_t getConnection(int timeoutMs = 5000);
    
    /**
     * @brief 归还连接
     * @param conn 要归还的连接
     * @param hasError 连接是否有错误
     */
    void returnConnection(amqp_connection_state_t conn, bool hasError = false);
    
    /**
     * @brief 获取连接池状态信息
     * @return 状态信息字符串
     */
    QString getStatus() const;
    
    /**
     * @brief 获取连接池统计信息
     * @return 统计信息结构体
     */
    struct PoolStatistics {
        int totalConnections;      ///< 总连接数
        int activeConnections;     ///< 活跃连接数
        int idleConnections;       ///< 空闲连接数
        int waitingRequests;       ///< 等待连接的请求数
        double averageWaitTime;    ///< 平均等待时间（毫秒）
    };
    
    PoolStatistics getStatistics() const;
    
    /**
     * @brief 设置连接池配置
     * @param config 新的连接配置
     */
    void updateConfig(const MQConnectionConfig& config);
    
    /**
     * @brief 清理连接池
     */
    void cleanup();
    

    
signals:
    
    /**
     * @brief 连接创建失败信号
     * @param error 错误信息
     */
    void connectionCreationFailed(const QString& error);
    
    /**
     * @brief 连接池统计信息更新信号
     * @param stats 统计信息
     */
    void statisticsUpdated(const PoolStatistics& stats);
    
private slots:
    
    /**
     * @brief 清理过期连接
     */
    void cleanupExpiredConnections();
    
private:
    /**
     * @brief 创建新连接
     * @return 连接状态指针，nullptr表示创建失败
     */
    amqp_connection_state_t createConnection();
    

    
    /**
     * @brief 关闭连接
     * @param conn 要关闭的连接
     */
    void closeConnection(amqp_connection_state_t conn);
    
    /**
     * @brief 查找连接信息
     * @param conn 连接状态指针
     * @return 连接信息指针，nullptr表示未找到
     */
    std::shared_ptr<MQConnectionInfo> findConnectionInfo(amqp_connection_state_t conn);
    

    
    /**
     * @brief 更新统计信息
     */
    void updateStatistics();
    
private:
    // 配置相关
    MQConnectionConfig m_config;                                    ///< 连接配置
    int m_maxConnections;                                           ///< 最大连接数
    int m_minConnections;                                           ///< 最小连接数
    int m_connectionTimeoutMs;                                      ///< 连接超时时间
    int m_maxIdleTimeMs;                                            ///< 最大空闲时间

    
    // 连接管理
    QList<std::shared_ptr<MQConnectionInfo>> m_connections;         ///< 连接列表
    mutable QMutex m_connectionsMutex;                              ///< 连接列表互斥锁
    QWaitCondition m_connectionAvailable;                          ///< 连接可用条件变量
    
    // 定时器
    std::unique_ptr<QTimer> m_cleanupTimer;                        ///< 清理定时器
    
    // 统计信息
    mutable QMutex m_statisticsMutex;                               ///< 统计信息互斥锁
    PoolStatistics m_statistics;                                   ///< 统计信息
    QQueue<QDateTime> m_waitTimes;                                  ///< 等待时间队列
    
    // 状态标志
    bool m_initialized;                                             ///< 是否已初始化
    bool m_shuttingDown;                                            ///< 是否正在关闭
};

#endif // MQCONNECTIONPOOL_H
